package com.qen.common;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ReflectUtil;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author licz
 * @data 2025年06月03日 11:51 AM
 */
public class ClassDescHelper {

    private static final Map<Class<?>, List<FieldCache>> CLASS_FIELD_LIST_CACHE = new ConcurrentHashMap<>();

    /**
     * 获取字段Map
     *
     * @param clazz
     * @return
     */
    public static Map<String, FieldCache> getFieldMap(Class<?> clazz) {
        List<FieldCache> list = getFieldList(clazz);
        Map<String, FieldCache> map = new HashMap<>();
        for (FieldCache f : list) {
            map.put(f.getField().getName(), f);
        }
        return map;
    }

    /**
     * 获取类的属性列表缓存
     *
     * @param clazz
     * @return
     */
    public static List<FieldCache> getFieldList(Class<?> clazz) {
        if (clazz == null) {
            return Collections.emptyList();
        }
        List<FieldCache> list = CLASS_FIELD_LIST_CACHE.get(clazz);
        if (CollectionUtil.isNotEmpty(list)) {
            return list;
        }
        Field[] fields = ReflectUtil.getFields(clazz);
        List<FieldCache> fieldCaches = new ArrayList<>();
        for (Field f : fields) {
            FieldCache fieldCache = new FieldCache(f, f.getType());
            fieldCache.setField(f);
            fieldCaches.add(fieldCache);
        }

        CLASS_FIELD_LIST_CACHE.put(clazz, fieldCaches);
        return fieldCaches;
    }

    /**
     * Collection字段的泛型
     */
    public static Class<?> getGenericType(Field field) {
        Type type = field.getGenericType();
        //没有写泛型
        if (!(type instanceof ParameterizedType)) {
            return Object.class;
        }
        ParameterizedType pt = (ParameterizedType) type;
        Type[] actualTypeArguments = pt.getActualTypeArguments();
        Type argument = actualTypeArguments[0];
        //通配符泛型 ? , ? extends XXX , ? super XXX
        if (argument instanceof WildcardType) {
            //获取上界
            Type[] types = ((WildcardType) argument).getUpperBounds();
            return (Class<?>) types[0];
        }
        return (Class<?>) argument;
    }

    /**
     * 获取表中的字段名
     *
     * @param clz
     * @param col
     * @return
     */
    public static String getTargetColumn(Class<?> clz, String col) {
        return BeetlUtils.getSQLManager().getNc().getColName(clz, col);
    }
}
